libobs_wrapper\data\properties/
mod.rs1mod enums;
2mod macros;
3pub mod prop_impl;
4pub mod types;
5
6use std::ffi::CStr;
7
8use libobs::obs_properties;
9use macros::*;
10
11pub use enums::*;
12use num_traits::FromPrimitive;
13use types::*;
14
15use crate::{run_with_obs, runtime::ObsRuntime, unsafe_send::Sendable, utils::{ObsError, ObsString}};
16
17#[derive(Debug, Clone)]
18pub enum ObsProperty {
19 Invalid(String),
21 Bool,
23 Int(ObsNumberProperty<i32>),
25 Float(ObsNumberProperty<f64>),
27 Text(ObsTextProperty),
29 Path(ObsPathProperty),
31 List(ObsListProperty),
33 Color(ObsColorProperty),
35 Button(ObsButtonProperty),
37 Font(ObsFontProperty),
39 EditableList(ObsEditableListProperty),
41 FrameRate(ObsFrameRateProperty),
43 Group(ObsGroupProperty),
45 ColorAlpha(ObsColorAlphaProperty),
47}
48
49#[cfg_attr(not(feature = "blocking"), async_trait::async_trait)]
50pub trait ObsPropertyObjectPrivate {
51 #[cfg_attr(feature = "blocking", remove_async_await::remove_async_await)]
52 async fn get_properties_raw(&self) -> Result<Sendable<*mut libobs::obs_properties_t>, ObsError>;
53 #[cfg_attr(feature = "blocking", remove_async_await::remove_async_await)]
54 async fn get_properties_by_id_raw<T: Into<ObsString> + Sync + Send>(id: T, runtime: ObsRuntime) -> Result<Sendable<*mut libobs::obs_properties_t>, ObsError>;
55}
56
57#[cfg_attr(feature = "blocking", remove_async_await::remove_async_await)]
58async fn get_properties_inner(
59 properties_raw: Sendable<*mut obs_properties>,
60 runtime: ObsRuntime,
61) -> Result<Vec<ObsProperty>, ObsError> {
62 let properties_raw = properties_raw.clone();
63 if properties_raw.0.is_null() {
64 return Ok(vec![]);
65 }
66
67 run_with_obs!(runtime, (properties_raw), move || {
68 let mut result = Vec::new();
69 let mut property = unsafe { libobs::obs_properties_first(properties_raw) };
70 while !property.is_null() {
71 let name = unsafe { libobs::obs_property_name(property) };
72 let name = unsafe { CStr::from_ptr(name as _) };
73 let name = name.to_string_lossy().to_string();
74
75 let p_type = unsafe { libobs::obs_property_get_type(property) };
76 let p_type = ObsPropertyType::from_i32(p_type);
77
78 match p_type {
79 Some(p_type) => {
80 result.push(p_type.to_property_struct(property));
81 }
82 None => result.push(ObsProperty::Invalid(name)),
83 }
84
85 unsafe { libobs::obs_property_next(&mut property) };
87 }
88
89 unsafe { libobs::obs_properties_destroy(properties_raw) };
90 result
91 }).await
92}
93
94#[cfg_attr(not(feature = "blocking"), async_trait::async_trait)]
96pub trait ObsPropertyObject: ObsPropertyObjectPrivate {
97 #[cfg_attr(feature = "blocking", remove_async_await::remove_async_await)]
99 async fn get_properties(&self) -> Result<Vec<ObsProperty>, ObsError>;
100
101 #[cfg_attr(feature = "blocking", remove_async_await::remove_async_await)]
102 async fn get_properties_by_id<T: Into<ObsString> + Sync + Send>(id: T, runtime: &ObsRuntime) -> Result<Vec<ObsProperty>, ObsError> {
103 let properties_raw = Self::get_properties_by_id_raw(id, runtime.clone()).await?;
104 get_properties_inner(properties_raw, runtime.clone()).await
105 }
106}